﻿using System.Text.Json.Serialization;
using BCore.Identity.Users.Caching;
using Core.Caching;
using Core.Domain.Entities;
using Core.Extensions;
using Core.Identity.Common.Interfaces.Common.Interfaces;
using Core.Identity.Users.Dtos;
using Core.Models;
using Gridify;
using Gridify.EntityFramework;
using MediatR;
using Microsoft.EntityFrameworkCore;

namespace Core.Identity.Users.Features.Queries.PaginationQuery;

#nullable disable

public class UsersWithPaginationQuery : GridifyQuery, ICacheableRequest<PaginatedData<UserDto>>
{
    /// <summary>
    /// 缓存键
    /// </summary>
    [JsonIgnore]
    public string CacheKey => UsersCacheKey.GetPaginationCacheKey($"{Page}_{PageSize}_{OrderBy}_{Filter}");
    /// <summary>
    /// 缓存选项
    /// </summary>
    [JsonIgnore]
    public IEnumerable<string> Tags => UsersCacheKey.Tags;
}

public class UsersWithPaginationQueryHandler :
         IRequestHandler<UsersWithPaginationQuery, PaginatedData<UserDto>>
{
    private readonly IIdentityDbContext _context;

    public UsersWithPaginationQueryHandler(
        IIdentityDbContext context)
    {
        _context = context;
    }

    public async Task<PaginatedData<UserDto>> Handle(UsersWithPaginationQuery request, CancellationToken cancellationToken)
    {
        var mapperConfig = new GridifyMapperConfiguration()
        {
            CaseSensitive = false,
            AllowNullSearch = true,
            IgnoreNotMappedFields = false,
            EntityFrameworkCompatibilityLayer = true
        };

        var mapper = new GridifyMapper<User>(mapperConfig)
            .GenerateMappings(2)
            .AddMap("phoneNumber", p => p.PhoneNumber.Value)
            .AddMap("organizationId", p => p.UserOrganizations.Select(x => x.OrganizationId));

        return (await _context.Users
            .Include(uo => uo.UserOrganizations)
                .ThenInclude(o => o.Organization)
            .AsNoTracking()
            .GridifyAsync(request, cancellationToken, mapper))
            .ToPaginatedList<User, UserDto>(request.Page, request.PageSize);
    }
}
